קרה לך שבדקת את הקוד והוא עבד. העלית אותו לשרת, אבל אחרי חודש גילית שגולשים מסוימים מקבלים שגיאה? היום נראה ונדבר על תפיסה וטיפול בשגיאות, איך ליידע עליהם את המפתח ולדאוג לגולש.
למה צריך לתפוס שגיאות
שני סיבות עיקריות עשויות לגרום לך לקרוא את כל הטקסט הזה:
[1] העובדה ששגיאות צריך לתקן וכדי לתקן צריך לדעת שהיו שגיאות, איזה שגיאות ואיפה
[2] וההסכמה שאתר עם 30 שגיאות בעמוד הראשי נראה לא ממש מגניב
איך לתפוס שגיאות
אנחנו כותבים פונקציה כלשהי (myfunction1 למשל) ואומרים למנוע ה-php שיפעיל אותה כל פעם שקוראת שגיאה. כדי להגיד למנוע ה-php לאיזה פונקציה לקרוא נשתמש בפונקציה מיוחדת set_error_handler.
function myfunction1()
{
echo 'oops, error <br/>';
}
set_error_handler('myfunction1');
echo 5 / 0; // Warning: Division by zero
echo $hi; // Notice: Undefined variable: hi
/*
oops, error <br/>
oops, error <br/>
*/
{
echo 'oops, error <br/>';
}
set_error_handler('myfunction1');
echo 5 / 0; // Warning: Division by zero
echo $hi; // Notice: Undefined variable: hi
/*
oops, error <br/>
oops, error <br/>
*/
מידע על השגיאה
הודעת שגיאה ב-PHP מורכבת מארבעה חלקים
Notice: Undefined variable hi in /script.php on line 8
[1] סוג השגיאה. יש כמה סוגי שגיאות (notice, warning, error, ..)
[2] טקסט השגיאה - עצם הבעיה
[3] הקובץ שבו קרתה השגיאה
[4] השורה שבה קרתה השגיאה
את ארבעת אלה php בשמחה מעבירה כפרמטרים לפונקציה שלנו באופן הבא:
function myfunction1($errtype, $message, $file, $line)
{
echo 'Oops an error ' , $message , ' happened in file ',
$file, ' on line ' , $line;
}
set_error_handler('myfunction1');
echo $hi;
// Oops an error Undefined variable hi happened in script.php on line 8
{
echo 'Oops an error ' , $message , ' happened in file ',
$file, ' on line ' , $line;
}
set_error_handler('myfunction1');
echo $hi;
// Oops an error Undefined variable hi happened in script.php on line 8
מה לעשות עם שגיאות?
לא להציג אותה למשתמש
טקסט השגיאה מכיל מידע פנימי על מבנה המערכת, הקבצים, התיקיות והשמות של הסקריפטים.
לספר מידע כזה לכל עובר דרך הוא לא רעיון טוב. עדיף להראות עמוד שגיאה מיוחד שפשוט יספר למשתמש שקרתה "תקלה במערכת. עמך הסליחה".
אפשר לבצעה העברה של המשתמש לעמוד השגיאה עם הפקודה header באופן הבא:
function myfunction1($errtype, $message, $file, $line)
{
header("Location: oops.html");
die();
}
set_error_handler('myfunction1');
echo $hi;
echo 'this will never happen';
{
header("Location: oops.html");
die();
}
set_error_handler('myfunction1');
echo $hi;
echo 'this will never happen';
לדווח למפתח
דיווח על כל שגיאה יישלח אליך למייל משם תוכל לעקוב אחריו ולטפל בו בהתאם:
תוכל להתאים את טקסט השגיאה למה שיראה לך נוח וקריא:
function myfunction1($errtype, $message, $file, $line)
{
$text = 'An error '.$message, ' in file '.$file.' on line '.$line;
mail('[email protected]', 'website error', $text);
header("Location: oops.html");
die();
}
set_error_handler('myfunction1');
echo $hi;
echo 'this will never happen';
{
$text = 'An error '.$message, ' in file '.$file.' on line '.$line;
mail('[email protected]', 'website error', $text);
header("Location: oops.html");
die();
}
set_error_handler('myfunction1');
echo $hi;
echo 'this will never happen';
יש דיווח, אבל אין שגיאה?
שגיאות מסוימות קוראות רק במצבים מסוימים ורק למשתמשים מסוימים. למה זה קורה?
יכול להיות שהם שלחו טופס עם נתונים ששברו את ההכנסה למסד, ערך כלשהו אצלם לא קיים בקוקי, נמחק משתנה כלשהו מהסשן בגלל באג בסקריפט אחר לגמרי או 1001 סיבות אחרות.
דיווח כמו בדוגמה למעלה לא יאפשר לך לאתר ולתקן את הבעיה בקלות.
הוספת נתונים על העמוד שבו נמצא, ערכי הפרמטרים של get ו post , נתוני הקוקי והסשן
יכולים לעזור בשחזור הבעיה וגילוי שגיאות שקוראות רק במקרים קיצוניים.
function myfunction1($errtype, $message, $file, $line)
{
$text = "An error $message in file $file on line $line \r\n
happened while visiting ".$_SERVER['QUERY_STRING']."\r\n\r\n".
"Session data is: ". print_r($_SESSION,1) . "\r\n\r\n" .
"Post data is: ". print_r($_POST,1) ;
mail('[email protected]', 'website error', $text);
header("Location: oops.html");
die();
}
set_error_handler('myfunction1');
echo $hi;
echo 'this will never happen';
{
$text = "An error $message in file $file on line $line \r\n
happened while visiting ".$_SERVER['QUERY_STRING']."\r\n\r\n".
"Session data is: ". print_r($_SESSION,1) . "\r\n\r\n" .
"Post data is: ". print_r($_POST,1) ;
mail('[email protected]', 'website error', $text);
header("Location: oops.html");
die();
}
set_error_handler('myfunction1');
echo $hi;
echo 'this will never happen';
כמה הערות כלליות
@ - לא מבטל שגיאות
גם אם הסימן הזה נמצא במקום כלשהו וקרתה בו שגיאה - הפונקציה myfunction1 תופעל
אגב, סימן @ מעיד על קוד גרוע. גם איתו php בכל זאת מפעילה את מנגנון השגיאה, הפונקציות הפנימיות שלה ומבזבזת על זה המון משאבים. ההבדל היחידי הוא, שלא מודפסת שורת ההודעה לדפדפן.
על תתעצל, תבדוק האם המשתנה קיים עם isset לפני שאתה משתמש בו. חסכת בבדיקה קטנה, הפסדת הרבה משאבים על טיפול פנימי של php בשגיאה.
error_reporting(0); באתר שלך
הודעות על שגיאות שמגיעות לידיים הלא נכונות עשויות להיות כלי חזק נגד ההבטחה של האתר. אל תתן ל-php להדפיס הודעות על שגיאות ללקוח.
שים לב שבזמן הפיתוח אתה דווקא חייב להשתמש ב error_reporting(E_ALL); כדי לדעת על כל שגיאה אפשרית. את כל השגיאות בקוד צריך לגלות במהלך הפיתוח והבדיקה, ולא אחרי.
שים שורה זו כשורה ראשונה בקוד. אפילו לפני session_start();
אל תשכח לבדוק את המייל. דיווחים עשויים להגיע :-)
ספר בתגובות איך אתה התמודדת או הולך להתמודד עם טיפול בשגיאות?
תגובות לכתבה:
וואו, נחמד מאוד:)
מונע FPD בצורה מושלמת!
תודה :)
מה זה fpd?
Full Path Dislosure -
בעיית אבטחה\תכנות..
הסקת מידע כל שהוא משגיאות שניתנות ע"י הרצה לא נכונה או מדרכים כלשהם להוציא שגיאה..
פה יש הסבר הרבה יותר ברור:
http://hakipedia.com/index.php/Full_Path_Disclosure
תודה. לא הכרתי את הקיצור הזה עד עכשיו.
ניסיתי אבל זה לא פול אל כל השגיאותת...
יש שגיאות קריטיות למפענח, כמו שגיאת סינטקס. הסקריפט
<?php ;+*/^&*; ?>
לא יפעל בכלל. מנוע ה-php לא הצליח לפענח את הקובץ
PARSE_ERROR
ובטח שלא הצליח ליצור את הפונקציה או להפעיל פקודה כלשהי.
שגיאות שלא נותנות למנוע ה-php להיטען - אי אפשר לתפוס.
שגיאות כאלה גם אין כל טעם לנסות לתפוס, אתה תראה אותם במהלך הפיתוח.
אם אתה מדבר על שגיאה מסוג אחר - תכתוב איזה שגיאה ועם איזה קוד אתה מקבל אותה.
כרגיל, מדריך מעולה, תודה. :)